<?php

namespace addons\websocketpush;

use app\common\library\Menu;
use think\Addons;
use think\Config;

/**
 * 插件
 */
class Websocketpush extends Addons
{
    /**
     * 插件安装方法
     * @return bool
     */
    public function install()
    {
        return true;
    }

    /**
     * 插件卸载方法
     * @return bool
     */
    public function uninstall()
    {
        return true;
    }

    /**
     * 插件启用方法
     * @return bool
     */
    public function enable()
    {
        return true;
    }

    /**
     * 插件禁用方法
     * @return bool
     */
    public function disable()
    {
        return true;
    }

    /**
     * 返回未编码的查询字符串
     * @param array $input http请求参数
     * @return string
     */
    protected static function queryString($input)
    {
        $queryString = '';
        foreach ($input as $key => $value) {
            $queryString .= $key . '=' . $value . '&';
        }
        return mb_substr($queryString, 0, -1);
    }

    /**
     * 生成添加对签名后的查询字符串
     * @param array $post 推送消息内容
     * @return string
     */
    protected static function sign($post)
    {
        $get = [
            'timestamp' => time(),
            'nonce' => uniqid()
        ];
        $getAndPost = array_merge($get, $post);
        natsort($getAndPost);
        $get['sign'] = hash('sha256', hash('sha256', self::queryString($getAndPost) . Config::get('token.key')));
        return self::queryString($get);
    }

    /**
     * 通过组名获取对应的用户id数组
     * @param array $names 组名数组
     * @return array 用户id数组
     */
    protected static function getAdminIdsByGroupNames($names)
    {
        return \app\admin\model\AuthGroup::whereIn('name', $names)->column('id');
    }

    /**
     * @param string $message 消息内容
     * @param array  $ids     管理员id数组
     * @return array 推送结果：0k为推送成功，No为推送失败
     */
    public static function pushToIds($message, $ids)
    {
        $protocol = get_addon_config('websocketpush')['cert'] ? 'https' : 'http';
        $results = [];
        $curl = curl_init();
        foreach ($ids as $id) {
            $post = [
                'type' => 'publish',
                'content' => htmlentities(trim($message)),
                'to' => $id
            ];
            $pushUrl = $protocol . '://' . $_SERVER['SERVER_ADDR'] . ':'
                . get_addon_config('websocketpush')['websocket_push_port']
                . '?'
                . self::sign($post);
            curl_setopt($curl, CURLOPT_URL, $pushUrl);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_POSTFIELDS, self::queryString($post));
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            if ($protocol === 'https') {
                curl_setopt($curl, CURLOPT_CAINFO, get_addon_config('websocketpush')['cert']);
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
            }
            $info = curl_exec($curl);
            if (curl_errno($curl)) {
                $results[$id] = 'No';
            } else {
                $results[$id] = $info;
            }
        }
        curl_close($curl);
        return $results;
    }

    /**
     * 给某个组下用户推送消息
     * @param string $message    消息内容
     * @param array  $groupNames 组名数组
     * @return array 推送结果
     */
    public static function pushToGroups($message, $groupNames)
    {
        return self::pushToIds($message, self::getAdminIdsByGroupNames($groupNames));
    }

    public function configInit(&$params)
    {
        $params['websocketpush'] = [
            'cert' => !!$this->getConfig()['cert'],
            'websocket_port' => $this->getConfig()['websocket_port']
        ];
        $params['websocketpush']['admin_id'] = session('admin.id');
    }
}
